package com.xfg.search.interceptor;

import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.xfg.search.annotation.PassToken;
import com.xfg.search.annotation.ValidateToken;
import com.xfg.search.entity.User;
import com.xfg.search.service.AdminService;
import com.xfg.search.service.UserService;
import jdk.internal.dynalink.support.NameCodec;
import org.springframework.lang.Nullable;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import com.auth0.jwt.JWT;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.List;

public class AuthenticationInterceptor  implements HandlerInterceptor {
    @Resource
    private AdminService adminService;

    //进入controller方法之前
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String token=request.getHeader("token");//从http的请求头中取出

        //如果不上方法则跳过
        if (!(handler instanceof HandlerMethod)){
            return true;
        }

        HandlerMethod handlerMethod=(HandlerMethod) handler;
        Method method=handlerMethod.getMethod();

        //如果controller这个方法上面有这个 @PassToken 注解  返回 true 不需要token验证放行
        if (method.isAnnotationPresent(PassToken.class)){
            PassToken passToken=method.getAnnotation(PassToken.class);
            if (passToken.required()){
                return true;
            }
        }

        //如果controller这个方法上面有这个 @ValidateToken 注解  返回 true token合格  否则token不合格教由全局异常处理
        if (method.isAnnotationPresent(ValidateToken.class)){
            ValidateToken validateToken=method.getAnnotation(ValidateToken.class);
            if (validateToken.required()){
                //开始token校验
                if (token==null){
                    throw new RuntimeException("请求头中没有token");
                }
                //取出创建token时塞入的用户名
                List<String> list = JWT.decode(token).getAudience();
                String username;
                String password;
                try {
                    username= JWT.decode(token).getAudience().get(0);
                    password=JWT.decode(token).getAudience().get(1);
                } catch (JWTDecodeException e) {
                    throw new RuntimeException("解析token异常");
                }

                User user=adminService.login(username,password);
                if (user==null){
                    throw new RuntimeException("当前用户不存在");
                }

                //验证token过期
                JWTVerifier jwtVerifier=JWT.require(Algorithm.HMAC256(user.getPassword())).build();
                try {
                    jwtVerifier.verify(token);
                } catch (JWTVerificationException e) {
                    throw new RuntimeException("token已过期请重新登录");
                }
                return true;
            }
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {

    }
}
